package cn.ecnu.note.service.impl;

import cn.ecnu.common.Constant;
import cn.ecnu.common.Permission;
import cn.ecnu.exception.RRXException;
import cn.ecnu.note.mapper.CommentMapper;
import cn.ecnu.note.mapper.ReplyMapper;
import cn.ecnu.note.pojo.Comment;
import cn.ecnu.note.pojo.Note;
import cn.ecnu.note.service.CommentService;
import cn.ecnu.note.service.ReplyService;
import cn.ecnu.note.vo.*;
import cn.ecnu.utils.PaginationUtil;
import cn.ecnu.vo.common.Pagination;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {


    @Resource
    private CommentMapper commentMapper;

    @Resource
    private ReplyMapper replyMapper;

    @Override
    public CommentVo addComment(CommentFrontVo vo) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(vo, comment);
        comment.setFlag(1); // 设置对应的flag
        commentMapper.addComment(comment);
        return commentMapper.getCommentVoById(comment.getCommentId());
    }

    @Override
    public ViewCommentVo getCommentByNoteId(Integer noteId, Integer pageNum) {
        int pageSize = 2;
        int totalSize = commentMapper.getCountByNoteId(noteId);

        Pagination pagination = PaginationUtil.paging(pageNum, totalSize, pageSize, "/comment/getCommentByNoteId/" + noteId);
        pageNum = pagination.getCurrentPage(); // 进行评论的分页

        List<CommentVo> commentVos = commentMapper.getCommentVosByNoteId(noteId, (pageNum - 1) * pageSize, pageSize); // 获取评论的vo
        List<CommentReplyVo>  comments = null;
        if (commentVos != null) {
            comments = commentVos.stream().map(commentVo -> {
                int replyPageSize = 2;
                int replyPageNum = 1;
                Integer commentId = commentVo.getCommentId(); // 获取评论的ID
                CommentReplyVo commentReplyVo = new CommentReplyVo();
                ViewReplyVo viewReplyVo = new ViewReplyVo();

                int replyTotalSize = replyMapper.getReplyCountByCommentId(commentId); // 获取这个评论下回复的总数目

                Pagination replyPagination = PaginationUtil.paging(replyPageNum, replyTotalSize, replyPageSize, "/reply/getReplyByCommentId/" + commentId);// 回复分页
                replyPageNum = replyPagination.getCurrentPage();

                commentReplyVo.setCommentInfo(commentVo); // 设置评论
                List<ReplyVo> replies = replyMapper.getReplyVoByCommentId(commentId, (replyPageNum - 1) * replyPageSize, replyPageSize); // 获取评论的第一页回复

                viewReplyVo.setRepliesInfo(replies);
                viewReplyVo.setPagination(replyPagination);
                commentReplyVo.setReplies(viewReplyVo); // 设置回复
                return commentReplyVo;
            }).collect(Collectors.toList());
        }
        ViewCommentVo vo = new ViewCommentVo();
        vo.setPagination(pagination);
        vo.setComments(comments);
        return vo;
    }

    @Override
    public ViewCommentVo getCommentByUserId(Integer userId, Integer pageNum) {
        int pageSize = 10; // TODO: pageSiz需要修改
        int totalSize = commentMapper.getCountByUserId(userId);

        Pagination pagination = PaginationUtil.paging(pageNum, totalSize, pageSize, "/comment/getCommentByUserId/" + userId);
        pageNum = pagination.getCurrentPage(); // 进行评论的分页

        List<CommentVo> commentVos = commentMapper.getCommentVosByUserId(userId, (pageNum - 1) * pageSize, pageSize); // 获取评论的vo
        List<CommentReplyVo>  comments = null;
        if (commentVos != null) {
            comments = commentVos.stream().map(commentVo -> {
                int replyPageSize = 10; //TODO: pageSize需要修改
                int replyPageNum = 1;
                Integer commentId = commentVo.getCommentId(); // 获取评论的ID
                CommentReplyVo commentReplyVo = new CommentReplyVo();
                ViewReplyVo viewReplyVo = new ViewReplyVo();
                int replyTotalSize = replyMapper.getReplyCountByCommentId(commentId); // 获取这个评论下回复的总数目

                Pagination replyPagination = PaginationUtil.paging(replyPageNum, replyTotalSize, replyPageSize, "/reply/getReplyByCommentId/" + commentId); // 回复分页
                replyPageNum = replyPagination.getCurrentPage();

                commentReplyVo.setCommentInfo(commentVo); // 设置评论
                List<ReplyVo> replies = replyMapper.getReplyVoByCommentId(commentId, (replyPageNum - 1) * replyPageSize, replyPageSize); // 获取评论的第一页回复
                viewReplyVo.setRepliesInfo(replies);
                viewReplyVo.setPagination(replyPagination);
                commentReplyVo.setReplies(viewReplyVo);
                return commentReplyVo;
            }).collect(Collectors.toList());
        }
        ViewCommentVo vo = new ViewCommentVo();
        vo.setPagination(pagination);
        vo.setComments(comments);
        return vo;
    }

    @Override
    public int deleteById(Integer commentId, Integer userId, Integer permission) {
        Comment  comment = commentMapper.getCommentById(commentId);
        if (comment == null) throw new RRXException(Constant.NO_RESOURCE.getMsg(), Constant.NO_RESOURCE.getCode());
        if (NumberUtils.compare(userId, comment.getUserId()) != 0 && !Permission.isAdmin(permission))
            throw new RRXException(Constant.NO_PERMISSION.getMsg(), Constant.NO_PERMISSION.getCode());
        // 最终删除
        return commentMapper.deleteCommentById(commentId);
    }

    @Override
    public List<AdminCommentVo> getAllComment(Integer uid, Integer nid, Integer pid) {
        List<AdminCommentVo> vo = commentMapper.getAllComment();
        if (uid != null) {
           vo = vo.stream().filter((v) -> {
                return NumberUtils.compare(v.getUserId(), uid) == 0;
            }).collect(Collectors.toList());
        }

        if (nid != null) {
            vo = vo.stream().filter((v) -> {
                return NumberUtils.compare(v.getNoteId(), nid) == 0;
            }).collect(Collectors.toList());
        }

        if (pid != null) {
            vo = vo.stream().filter((v) -> {
                return NumberUtils.compare(v.getPaperId(), pid) == 0;
            }).collect(Collectors.toList());
        }
        return vo;
    }
}
